nom, eating data byte by byte
nom is a parser combinator library with a focus on safe parsing,
streaming patterns, and as much as possible zero copy.
The code is available on [Github](https://github.com/Geal/nom)
There are a few [guides](home.html) with more details
about [the design of nom](how_nom_macros_work.html),
[how to write parsers](making_a_new_parser_from_scratch.html),
or the [error management system](error_management.html).
If you are upgrading to nom 2.0, please read the
[migration document](upgrading_to_nom_2.html).
See also the [FAQ](FAQ.html).
# Example
```
#[macro_use]
extern crate nom;
use nom::{IResult,digit};
// Parser definition
use std::str;
use std::str::FromStr;
// We parse any expr surrounded by parens, ignoring all whitespaces around those
named!(parens, ws!(delimited!( tag!("("), expr, tag!(")") )) );
// We transform an integer string into a i64, ignoring surrounding whitespaces
// We look for a digit suite, and try to convert it.
// If either str::from_utf8 or FromStr::from_str fail,
// we fallback to the parens parser defined above
named!(factor, alt!(
map_res!(
map_res!(
ws!(digit),
str::from_utf8
),
FromStr::from_str
)
| parens
)
);
// We read an initial factor and for each time we find
// a * or / operator followed by another factor, we do
// the math by folding everything
named!(term , do_parse!(
init: factor >>
res: fold_many0!(
pair!(alt!(tag!("*") | tag!("/")), factor),
init,
|acc, (op, val): (&[u8], i64)| {
if (op[0] as char) == '*' { acc * val } else { acc / val }
}
) >>
(res)
)
);
named!(expr , do_parse!(
init: term >>
res: fold_many0!(
pair!(alt!(tag!("+") | tag!("-")), term),
init,
|acc, (op, val): (&[u8], i64)| {
if (op[0] as char) == '+' { acc + val } else { acc - val }
}
) >>
(res)
)
);
fn main() {
assert_eq!(expr(b"1+2"), IResult::Done(&b""[..], 3));
assert_eq!(expr(b"12+6-4+3"), IResult::Done(&b""[..], 17));
assert_eq!(expr(b"1+2*3+4"), IResult::Done(&b""[..], 11));
assert_eq!(expr(b"(2)"), IResult::Done(&b""[..], 2));
assert_eq!(expr(b"2*(3+4)"), IResult::Done(&b""[..], 14));
assert_eq!(expr(b"2*2/(5-1)+3"), IResult::Done(&b""[..], 4));
}
```